#!/bin/sh
set -e

SCRIPT_DIR=$(realpath $(dirname "$0"))
CURRENT_DIR=$(realpath $(pwd))

WORKDIR=$CURRENT_DIR/abuild
LOG_DIR=$WORKDIR/logs

ARCH=$(uname -m)
REPO_FILE=""
MAXJ="$(nproc)"
CPU_SETS="0-$(($MAXJ - 1))"
IMG_NAME="fedora"
CONF_SRC=""

PATH=$SCRIPT_DIR:$PATH
source $SCRIPT_DIR/common.sh

function usage()
{
    cat <<EOF
Usage:
./$(basename $0) -a [aarch64|x86_64] -r [repo] -d [work dir] -j [max available cpu] -t [docker image] -l [list of source path]
EOF
}

function param_parse()
{
    while getopts "a:r:d:j:t:l:" opt
    do
        case "$opt" in
            a)
            ARCH="$OPTARG";;
            r)
            REPO_FILE="$OPTARG";;
            d)
            WORKDIR="$OPTARG";;
            j)
            MAXJ="$OPTARG";;
            t)
            IMG_NAME="$OPTARG";;
            l)
            CONF_SRC="$OPTARG";;
            ?)
            log_error "unknown parameters" && usage && return 1;;
        esac
    done

    [[ ! -n $ARCH ]] && log_error "empty parameter, -a" && usage && return 1
    [[ ! -n $REPO_FILE ]] && log_error "empty parameter, -r" && usage && return 1
    [[ ! -n $WORKDIR ]] && log_error "empty parameter, -d" && usage && return 1
    [[ ! -n $MAXJ ]] && log_error "empty parameter, -j" && usage && return 1
    [[ ! -n $IMG_NAME ]] && log_error "empty parameter, -t" && usage && return 1
    [[ ! -n $CONF_SRC ]] && log_error "empty parameter, -c" && usage && return 1

    ( [[ $ARCH != "aarch64" ]] && [[ $ARCH != "x86_64" ]] ) && usage && return 1

    REPO_FILE=$(realpath $REPO_FILE)
    [[ ! -f $REPO_FILE ]] && log_error "repo file not exit" && usage && return 1

    WORKDIR=$(realpath $WORKDIR)
    [[ ! -d $WORKDIR ]] && log_error "work dir not exist" && usage && return 1
    LOG_DIR=$WORKDIR/logs

    [[ $MAXJ -lt 1 ]] && log_error "maxj invalid" && usage && return 1
    CPU_SETS="0-$(($MAXJ - 1))"

    CONF_SRC=$(realpath $CONF_SRC)
    [[ ! -f $CONF_SRC ]] && log_error "configure file not exist" && usage && return 1

    return 0
}

function directory_init()
{
    local clearflag=$1

    [[ $clearflag == 1 ]] && [[ -d $WORKDIR ]] && rm -rf $WORKDIR
    mkdir -p $WORKDIR

    [[ $clearflag == 1 ]] && [[ -d $LOG_DIR ]] && rm -rf $LOG_DIR
    mkdir -p $LOG_DIR
}

# some info message
function wait_print()
{
    local all=$1

    local lcnt=$(cat $flagf | wc -l)
    while [[ $lcnt -lt $all ]]; do
        log_info "[$(date +'%Y-%m-%d %H:%M:%S')]compile $lcnt/$all"
        sleep 30
        local lcnt=$(cat $flagf | wc -l)
    done
}

function allspec_dockerbuild()
{
    param_parse $@
    directory_init 0

    local srclist=$CONF_SRC

    local allcnt=$(keylist_cnt $srclist)
    local confbase=$(dirname $srclist)

    # some info message
    local flagf=$WORKDIR/cnt.log
    [[ -f $flagf ]] && rm -f $flagf
    touch $flagf
    wait_print $allcnt &

    for ccnt in $(seq 1 $allcnt)
    do
        local sdir=$(realpath $(keylist_read_val $srclist "num" $ccnt))
        local sname=$(basename $sdir /)
        (
            log_info "[${ccnt}/${allcnt}][$sname] building in $CPU_SETS..."
            local tmpworkdir=$WORKDIR/$sname
            mkdir -p $tmpworkdir
            set +e
            local buildopt="-a $ARCH -r $REPO_FILE -t $IMG_NAME -s $sdir -d $tmpworkdir -c $CPU_SETS"
            buildrpmfordocker $buildopt > $LOG_DIR/$sname.log 2>&1
            set -e
            log_info "[${ccnt}/${allcnt}][$sname] build result \$?=$?"
            # for some info message
            echo $sname >> $flagf
        ) &
        [[ $(jobs -r -p | wc -l) -ge $((MAXJ + 1)) ]] && wait -n
    done
    wait || log_error "some jobs exec error"
}

allspec_dockerbuild $@

